#ifndef __SAFE_VECTOR_HPP__
#define __SAFE_VECTOR_HPP__

#include <vector>
#include <algorithm>


/***********************************************************************
实现在容器遍历时删除元素
遍历前lock();
遍历后unlock();
***********************************************************************/
template <typename T>
class SafeVector
{
    int _locks = 0;
    inline unsigned char isLock() {
        return _locks > 0;
    }
    std::vector<T> _vec;
    std::vector<T> _removeVec;
    std::vector<T> _addVec;
    void _processRemove() {
        if ( isLock() ) {
            return;
        }
        if ( _removeVec.size() > 0 ) {
            auto iter = _removeVec.begin();
            while ( iter != _removeVec.end() ) {
                auto& cell = ( *iter );
                remove( cell );
                iter++;
            }
        }

        _removeVec.clear();
    }
    void _processAdd() {
        if ( isLock() ) {
            return;
        }
        if ( _addVec.size() > 0 ) {
            auto iter = _addVec.begin();
            while ( iter != _addVec.end() ) {
                auto& cell = ( *iter );
                push( cell );
                iter++;
            }
        }

        _addVec.clear();
    }
    typedef typename std::vector<T>::iterator iterator;
    typedef typename std::vector<T>::const_iterator const_iterator;
    typedef typename std::vector<T>::reverse_iterator reverse_iterator;
    typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
public:
    ~SafeVector() {
        _vec.clear();
    }
    const std::size_t size() const {
        return _vec.size();
    }

    void push( T && cell ) {
        if ( isLock() ) {
            _addVec.push_back( cell );
        }
        else {
            _vec.push_back( cell );
        }
    }
    void push( T const& cell ) {
        if ( isLock() ) {
            _addVec.push_back( cell );
        }
        else {
            _vec.push_back( cell );
        }
    }

    iterator erase( iterator iter ) {
        return _vec.erase( iter );
    }
    iterator erase( const_iterator citer ) {
        return _vec.erase( citer );
    }

    void remove( T && cell ) {
        if ( isLock() ) {
            _removeVec.push_back( cell );
        }
        else {
            auto iter = std::find( begin(), end(), cell );
            if ( iter != end() ) {
                erase( iter );
            }
        }
    }
    void remove( T const& cell ) {
        if ( isLock() ) {
            _removeVec.push_back( cell );
        }
        else {
            auto iter = std::find( begin(), end(), cell );
            if ( iter != end() ) {
                erase( iter );
            }
        }
    }
    void lock() {
        _locks++;
    }
    void unlock() {
        _locks--;

        if ( !isLock() ) {
            _processRemove();
            _processAdd();
        }
    }

    void clear() {
        _vec.clear();
    }

    iterator begin() { return _vec.begin(); }
    iterator end() { return _vec.end(); }
    reverse_iterator rbegin() { return _vec.rbegin(); }
    reverse_iterator rend() { return _vec.rend(); }

    const_iterator begin() const { return _vec.begin(); }
    const_iterator end()	const { return _vec.end(); }
    const_reverse_iterator rbegin() const { return _vec.rbegin(); }
    const_reverse_iterator rend() const { return _vec.rend(); }


     T& operator[]( const std::size_t _Pos )
    {
        return _vec[_Pos];
    }

     const T& operator[]( const std::size_t _Pos ) const
    {
        return _vec[_Pos];
    }

     T& at( const std::size_t _Pos )
    {
        _vec.at( _Pos );
    }

     const T& at( const std::size_t _Pos ) const
    {
        _vec.at( _Pos );
    }
};


#endif // !__SAFE_VECTOR_HPP__
